package tdomhan.addict.dictionary;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.Date;

/**
 * Creates a dictionary in the stardict format according to:
 * http://stardict.sourceforge.net/StarDictFileFormat
 * That can be read from applications like Colordict on Android.
 * FIXME: the index file is not sorted using the stardict_strcmp() function, which might lead to problems
 * @author tobi
 *
 */
public class StardictFile {
	OutputStreamWriter ifoFileWriter;
	OutputStreamWriter dictFileWriter;
	OutputStreamWriter idxFileWriter;
	DataOutputStream ifoFile;
	DataOutputStream idxFile;
	DataOutputStream dictFile;
	
	String bookName;
	String description;
	String author;
	String website;
	String email;
	
	int numberOfWords=0;
	
	long previousDictOffset=0;
	
	StardictFile(DataOutputStream ifoFile,
			DataOutputStream idxFile,
			DataOutputStream dictFile,
			String bookName,
			String description, 
			String author,
			String website,
			String email) throws UnsupportedEncodingException {
		this.idxFile = idxFile;
		this.dictFile = dictFile;
		this.ifoFile = ifoFile;
		
		this.bookName = bookName;
		this.description = description;
		this.author = author;
		this.website = website;
		this.email = email;
		
		ifoFileWriter = new OutputStreamWriter(ifoFile, "UTF8");
		dictFileWriter = new OutputStreamWriter(dictFile, "UTF8");
		idxFileWriter = new OutputStreamWriter(idxFile, "UTF8");
	}
	
	/**
	 * write an entry to the dictionary.
	 * successive calls must correspond to an increasing index.
	 * @param entry
	 * @param indexStr must be higher then the last indexStr
	 * @throws IOException 
	 */
	public void writeEntry(String indexStr, String entry) throws IOException {
		idxFileWriter.append(indexStr);
		idxFileWriter.append("\0");
		idxFileWriter.flush();
		idxFile.writeInt((int)previousDictOffset);
		
		dictFileWriter.append(entry);
		dictFileWriter.flush();
		long dictOffset = dictFile.size();
		long entrySize = dictOffset-previousDictOffset;
		idxFile.writeInt((int)entrySize);
		
		previousDictOffset = dictOffset;
		numberOfWords++;
	}
	
	/**
	 * write the ifo file.
	 * the last function that will be called before finishing the file.
	 * @throws IOException
	 */
	public void writeInfo() throws IOException {
		idxFile.flush();
		
		ifoFileWriter.append("StarDict's dict ifo file\n");
		ifoFileWriter.append("version=2.4.2\n");
		ifoFileWriter.append("wordcount="+numberOfWords+"\n");
		ifoFileWriter.append("idxfilesize="+idxFile.size()+"\n");
		ifoFileWriter.append("bookname="+bookName+"\n");
		ifoFileWriter.append("description="+description+", contains "+numberOfWords+" words."+"\n");
		ifoFileWriter.append("author="+author+"\n");
		ifoFileWriter.append("email="+email+"\n");
		ifoFileWriter.append("website="+website+"\n");
		ifoFileWriter.append("date="+new Date().toString()+"\n");
		ifoFileWriter.append("sametypesequence=m\n");
	}
	
	/**
	 * finish all files, closes all streams.
	 */
	public void finish() {
		try {
			ifoFileWriter.close();
			dictFileWriter.close();
			idxFileWriter.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
